#include "App.hpp"

// Public
// Functons

/*static*/ App& App::I()
{
  if (instance == NULL)
    instance = new App();
  return (*instance);
}

void App::CreateAppWindow (std::string title)
{
  if (windowAlreadyCreated)
    return;

  // read in the .ini file
  std::string appSettingsLocation = "resources/config/settings.ini";
  Settings appSettings = Settings::Load(appSettingsLocation);

  // declare and specify default values
  fullscreen = false;
  int winW = 800, winH = 600,
      fulW = 1024, fulH = 768;
  int AAlevel = 0, framerateLimit = 0;

  if (appSettings.IsEmpty())
  {
    // File wasn't found, so try to write the defaults for next time
    appSettings.SetBool("fullscreen", fullscreen);
    appSettings.SetInt("windowed_width", winW);
    appSettings.SetInt("windowed_height", winH);
    appSettings.SetInt("fullscreen_width", fulW);
    appSettings.SetInt("fullscreen_height", fulH);
    appSettings.SetInt("AA_level", AAlevel);
    appSettings.SetInt("framerate_limit", framerateLimit);
    appSettings.Save();
  }
  else
  {
    // read in the settings from the file, still specifying default alts
    fullscreen = appSettings.GetBool("fullscreen", false);
    winW = appSettings.GetInt("windowed_width", winW);
    winH = appSettings.GetInt("windowed_height", winH);
    fulW = appSettings.GetInt("fullscreen_width", fulW);
    fulH = appSettings.GetInt("fullscreen_height", fulH);
    AAlevel = appSettings.GetInt("AA_level", AAlevel);
    framerateLimit = appSettings.GetInt("framerate_limit", framerateLimit);
  }

  // now create the window

  int targetWidth = (fullscreen) ? (fulW) : (winW);
  int targetHeight = (fullscreen) ? (fulH) : (winH);
  sf::VideoMode targetMode(targetWidth, targetHeight, 32);  // 32 bpp video mode
  //targetMode = sf::VideoMode::GetDesktopMode();

  windowSettings = sf::ContextSettings(32/*bpp*/, 8/*stencil*/, AAlevel);

  if (!fullscreen)
  {
    currentWindow.create(
          targetMode,
          title, sf::Style::Default, windowSettings );
//          sf::Style::Resize | sf::Style::Close | sf::Style::Titlebar,
//          windowSettings);
  }
  else
  {
    currentWindow.create(
          targetMode,
          title, sf::Style::Fullscreen, windowSettings );
//          sf::Style::Fullscreen,
//          windowSettings);
    currentWindow.setPosition(sf::Vector2i(0,0));
  }
  currentWindow.setFramerateLimit(framerateLimit);

  windowAlreadyCreated = true;
  running = true;
}

sf::RenderWindow &App::GetWindow()
{
  return (currentWindow);
}


Vec2i App::Size()
{
  return Vec2i(currentWindow.getSize().x, currentWindow.getSize().y);
}

App::MouseModes App::MouseMode(MouseModes state)
{
  if (state != None)
    mouseMode = state;
  return mouseMode;
}

App::MouseModes App::MouseMode()
{
  return mouseMode;
}

Vec2i App::MousePosition ()
{
  return Vec2i(sf::Mouse::getPosition(currentWindow).x, currentWindow.getSize().y - sf::Mouse::getPosition(currentWindow).y);
}

Vec3d App::ClearColor(Vec3d clr)
{
  if (clr.x >= 0 && clr.y >= 0 && clr.z >= 0 &&
      clr.x <= 1 && clr.y <= 1 && clr.y <= 1)
    clearColor = clr;
  return clearColor;
}

void App::SetTitle(std::string newTitle)
{
  currentWindow.setTitle(newTitle);
}

bool App::Fullscreen()
{
  return fullscreen;
}

void App::Exit()
{
  running = false;
}

bool App::Running()
{
  return running;
}

/*static*/ bool App::Cleanup()
{
  // only delete the instance if the program isn't running anymore
  if (!instance->Running())
  {
    instance->GetWindow().close();
    //delete instance;  // this needs to be deleted, but bloody thing ... gives me an error. Since this only occurs once, its not a problem, though its a mem leak nontheless
    return true;
  }
  return false;
}

// Private
// Functionss

App::App()
{
  running = false;
  windowAlreadyCreated = false;
  clearColor = Vec3d(0, 1, 0);
}

App::App(const App& otherWindow)
{
  // do nothing
}

void App::operator = (const App& otherWindow)
{
  // do nothing
}

// Variables

/*static*/ App* App::instance = NULL;
